package com.songlanyun.modules.donation.service.impl;

import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.songlanyun.common.enums.DonationConstant;
import com.songlanyun.common.enums.IntegralConstant;
import com.songlanyun.common.exception.RRException;
import com.songlanyun.common.utils.BeanUtil;
import com.songlanyun.common.utils.custom.MathUtils;
import com.songlanyun.common.validator.ValidatorUtils;
import com.songlanyun.modules.donation.model.DonationEntityAuditDTO;
import com.songlanyun.modules.donation.model.DonationEntityDTO;
import com.songlanyun.modules.exception.DonationExceptionEnum;
import com.songlanyun.modules.integralrecord.entity.IntegralRecord;
import com.songlanyun.modules.integralrecord.service.IntegralRecordService;
import com.songlanyun.modules.pointsexchangeconfig.entity.PointsExchangeConfigEntity;
import com.songlanyun.modules.pointsexchangeconfig.service.PointsExchangeConfigService;
import com.songlanyun.modules.publicbenefitmsg.model.to.PublicBenefitMsgTO;
import com.songlanyun.modules.publicbenefitmsg.service.PublicBenefitMsgService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.Map;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.songlanyun.common.utils.PageUtils;
import com.songlanyun.common.utils.Query;

import com.songlanyun.modules.donation.dao.DonationDao;
import com.songlanyun.modules.donation.entity.DonationEntity;
import com.songlanyun.modules.donation.service.DonationService;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.validation.constraints.NotNull;


@Service("donationService")
public class DonationServiceImpl extends ServiceImpl<DonationDao, DonationEntity> implements DonationService {

    @Autowired
    private IntegralRecordService integralRecordService;

    @Resource
    private PointsExchangeConfigService pointsExchangeConfigService;

    @Override
    public DonationEntity create(DonationEntity entity) {
        this.baseMapper.insert(entity);
        return entity;
    }

    @Override
    public DonationEntity modify(DonationEntity entity) {
        this.baseMapper.updateById(entity);
        return entity;
    }

    @Override
    public void remove(Long id) {
        DonationEntity donationEntity = loadById(id, true);
        if (!DonationConstant.DonationStatus.WAIT.equals(donationEntity.getStatus())) {
            throw new RRException("只有未处理的捐赠才可以删除");
        }
        this.removeById(id);
    }

    @Override
    public PageUtils queryPage(Map<String, Object> params) {

        String contactPerson = MapUtil.getStr(params, "contact_person");
        String contactPhone = MapUtil.getStr(params, "contact_phone");
        Integer status = MapUtil.getInt(params, "status");
        Long userId = MapUtil.getLong(params, "user_id");
        IPage<DonationEntity> page = this.page(
                new Query<DonationEntity>().getPage(params),
                new LambdaQueryWrapper<DonationEntity>()
                        .like(StringUtils.isNotBlank(contactPerson), DonationEntity::getContactPerson, contactPerson)
                        .like(StringUtils.isNotBlank(contactPhone), DonationEntity::getContactPhone, contactPhone)
                        .eq(ObjectUtil.isNotNull(status) && status > -1, DonationEntity::getStatus, status)
                        .eq(ObjectUtil.isNotNull(userId), DonationEntity::getUserId, userId)
                        .orderByDesc(DonationEntity::getApplyTime)
        );

        return new PageUtils(page);
    }

    @Override
    public void apply(DonationEntityDTO dto) {
        ValidatorUtils.validateEntity(dto);
        DonationEntity donationEntity = new DonationEntity();
        BeanUtil.copyPropertiesIgnoreNull(dto, donationEntity);
        donationEntity.setStatus(DonationConstant.DonationStatus.WAIT);
        donationEntity.setApplyTime(new Date());
        this.create(donationEntity);
    }

    @Override
    public DonationEntity loadById(Long id, boolean tw) {
        DonationEntity obj = this.getById(id);
        if (ObjectUtil.isNull(obj) && tw) {
            throw new RRException("没有找到编号为" + id + "的捐赠");
        }
        return obj;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public DonationEntity audit(DonationEntityAuditDTO dto) {
        ValidatorUtils.validateEntity(dto);
        DonationEntity donationEntity = loadById(dto.getId(), true);
        if (DonationConstant.DonationStatus.WAIT != donationEntity.getStatus()) {
            throw new RRException(DonationExceptionEnum.THE_CURRENT_PUBLIC_WELFARE_DONATION_HAS_BEEN_REVIEWED);
        }
        donationEntity.setStatus(DonationConstant.DonationStatus.getByCode(dto.getStatus()));
        donationEntity.setAuditAdmin(dto.getAuditAdmin());
        donationEntity.setFactItemName(dto.getFactItemName());
        donationEntity.setFactItemAmount(dto.getFactItemAmount());
        donationEntity.setFactInterestAmount(dto.getFactInterestAmount());
        donationEntity.setAuditTime(new Date());
        donationEntity.setNoDonationRemark(dto.getNoDonationRemark());
        //已捐
        if (donationEntity.getStatus().equals(DonationConstant.DonationStatus.YES)) {
            BigDecimal points = BigDecimal.ZERO;
            //获得的公益积分
            PointsExchangeConfigEntity config = pointsExchangeConfigService.loadConfig(false);
            if (ObjectUtil.isNotNull(config) && ObjectUtil.isNotNull(config.getDonationExchangeRatio())) {
                BigDecimal factInterestAmount = ObjectUtil.isNull(donationEntity.getFactInterestAmount()) ? BigDecimal.ZERO : donationEntity.getFactInterestAmount();
                BigDecimal factItemAmount = ObjectUtil.isNull(donationEntity.getFactItemAmount()) ? BigDecimal.ZERO : donationEntity.getFactItemAmount();
                BigDecimal donationExchangeRatio = config.getDonationExchangeRatio();
                points = MathUtils.add(MathUtils.multiply(factInterestAmount, donationExchangeRatio), MathUtils.multiply(factItemAmount, donationExchangeRatio));
            }

            //保存积分记录
//            IntegralRecord record = new IntegralRecord(donationEntity.getUserId(), points, IntegralConstant.InnerMode.WELFARE_DONATION,
//                    IntegralConstant.IntegralModelType.WELFARE_DONATION, donationEntity.getId(), "公益捐款获得积分");
//            integralRecordService.inner(record);

            donationEntity.setGivePoint(points);
        }

        this.modify(donationEntity);
        return donationEntity;
    }

    @Override
    public void removeMy(Long id, Long userId) {
        DonationEntity donationEntity = loadById(id, true);
        if (!donationEntity.getUserId().equals(userId)) {
            throw new RRException("只能删除自己的申请");
        }
        if (!DonationConstant.DonationStatus.WAIT.equals(donationEntity.getStatus())) {
            throw new RRException("只有未处理的捐赠才可以删除");
        }
        this.removeById(id);
    }


}
